#include "kernel/types.h"
#include "user/user.h"
#include "kernel/stat.h"
#include "kernel/fs.h"
#define MAX_PATH 512
#define MAX_NAME 64

// 从路径中提取文件名
char* fmtname(char *path) {
    static char buf[MAX_NAME];
    int i = 0;
    char *p;
    for(p=path+strlen(path); p>=path && *p!='/'; p--)
        ;
    p++;
    while (*p && i < MAX_NAME - 1) {
        buf[i++] = *p++;
    }
    buf[i] = '\0';
    return buf;
}

// 比较文件名并打印路径
void cmp(char *a, char *b) {
    if(strcmp(fmtname(a), b) == 0)
        printf("%s\n", a);
}

// 递归查找文件
void find(char *path, char *filename) {
    char buf[MAX_PATH];
    int fd, n;
    struct dirent de;
    struct stat st;

    // 打开路径
    fd = open(path, 0);
    if(fd < 0) {
        fprintf(2, "find: cannot open %s\n", path);
        return;
    }

    // 读取目录内容
    while((n = read(fd, &de, sizeof(de))) > 0) {
        if(de.inum == 0)
            continue;
        memset(buf, 0, MAX_PATH);
        strcpy(buf, path);
        char *p = buf + strlen(buf);
        if(p != buf && p[-1] != '/')
            *p++ = '/';
        int i = 0;
        while (de.name[i] && i < DIRSIZ - 1) {
            p[i] = de.name[i];
            i++;
        }
        p[i] = '\0';


        if(stat(buf, &st) < 0) {
            fprintf(2, "find: cannot stat %s\n", buf);
            continue;
        }
        if(strcmp(de.name, filename) == 0) {
            cmp(buf, filename);
        }
        // 如果有目录，递归查找
        if(st.type == T_DIR && strcmp(de.name, ".") != 0 && strcmp(de.name, "..") != 0) {
            find(buf, filename);
        }

    }
    close(fd);
}

int main(int argc, char *argv[]) {
    if(argc != 3) {
        fprintf(2, "Usage: find dirName fileName\n");
        exit(1);
    }
    find(argv[1], argv[2]);
    exit(0);
}